package database;


import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;


import model.DbAdapter;

import serverMessage.ServerMessage;

/**
 * class UsersStatus - singleton, observable - save for each user queue of messages from the server
 */
public class UsersStatus extends Observable {
	
	//the singleton
	private static UsersStatus usersStatus = new UsersStatus();	
	
	//hash map of user and its messages queue
	private ConcurrentHashMap<String, ConcurrentLinkedQueue<ServerMessage>> messageQueue = new ConcurrentHashMap<String, ConcurrentLinkedQueue<ServerMessage>>();
	
	//private ctor
	private UsersStatus() {	}
	
	/**
	 * @return an instance of UsersStatus class (singleton)
	 */
	public static UsersStatus getInstance()
	{
		return usersStatus;	
	}
	
	/**
	 * sign the observer for updates of this observable - when a user get a message
	 * @param observer - an observer
	 * @return a hash map of the users status (for reading from it)
	 */
	public ConcurrentHashMap<String, ConcurrentLinkedQueue<ServerMessage>> addObserverOnUsersStatus(Observer observer) {
		usersStatus.addObserver(observer);
		return messageQueue;
	}
	
	/**
	 * add the message to each of the users 
	 * @param usersID - a list of users
	 * @param message - a message to those users
	 */
	public void addMessage(List<String> usersID, ServerMessage message)
	{
		//System.out.println("add message");
		System.out.println("users "+ usersID + " message: "+ message);
		
		if (usersID==null)
			return;
		
		Iterator<String> iterator = usersID.iterator();
		ServerMessage userMessage;

		if ((iterator!=null) && (iterator.hasNext()))
		{
			//for each user
			while (iterator.hasNext())
			{	
				String oneUser = iterator.next();
				ConcurrentLinkedQueue<ServerMessage> userQueue = messageQueue.get(oneUser);
				
				//create the message
				userMessage = new ServerMessage(oneUser, message.getKindRequest(), DbAdapter.getInstance().getFolderName(oneUser, Integer.parseInt(message.getFolderName())), message.getFileName(), message.getByteFile());
				
				//if he already has a message queue - just add, else create it first
				if (userQueue!=null)
				{
					userQueue.add(userMessage);
				}
				else
				{
					userQueue = new ConcurrentLinkedQueue<ServerMessage>();
					userQueue.add(userMessage);
					messageQueue.put(oneUser, userQueue);					
				}
			}
			
			//notify to the observers which users has been changed
			usersStatus.setChanged();
			usersStatus.notifyObservers(usersID);
		
		}
		
		
	}
	
	/**
	 * add the message to the user 
	 * @param userID - a user
	 * @param message - a message to this user
	 */
	public void addMessage(String userID, ServerMessage message)
	{
		System.out.println("add messager for one user");
		LinkedList<String> list = new LinkedList<String> ();
		list.add(userID);
		addMessage(list, message);		
	}
	
	
	/**
	 * add the messages to the user 
	 * @param userID - a user
	 * @param messages - a list of messages
	 */
	public void addMessage(String userID, List<ServerMessage> messages)
	{
		if ((userID==null)||(messages==null))
			return;
		
		Iterator<ServerMessage> iterator = messages.iterator();
		ConcurrentLinkedQueue<ServerMessage> userQueue = messageQueue.get(userID);
		ServerMessage userMessage;
		
		if ((iterator!=null) && (iterator.hasNext()))
		{
			//add all of the messages to the user queue
			while (iterator.hasNext())
			{	
				ServerMessage message = iterator.next();
				
				userMessage = new ServerMessage(userID, message.getKindRequest(), DbAdapter.getInstance().getFolderName(userID, Integer.parseInt(message.getFolderName())), message.getFileName(), message.getByteFile());
				
				if (userQueue!=null)
				{
					userQueue.add(userMessage);
				}
				else
				{
					userQueue = new ConcurrentLinkedQueue<ServerMessage>();
					userQueue.add(userMessage);
					messageQueue.put(userID, userQueue);					
				}
			}
			
			//just for the notify (cause it's expect to a list of users)
			LinkedList<String> list = new LinkedList<String> ();
			list.add(userID);
			
			//System.out.println("notify");
			usersStatus.setChanged();
			usersStatus.notifyObservers(list);
		
		}			
	}
	
	/*public ConcurrentLinkedQueue<ServerMessage> getUserQueue(String userID)
	{
		return messageQueue.get(userID);
	}*/
	

}
